package mips.instructions;

/**
 * <code>TNE</code> instruction<br/>
 * Trap If Not Equal<br/>
 * @author jnmartin84@gmail.com
 */
public class TNE extends Instruction {

	private static final TNE INSTANCE = new TNE();
	private static final String INSTRUCTION_NAME = "TNE";

	private TNE(){}

	public static final TNE getInstance() {
		return INSTANCE;
	}

	/**
	 * Format:<br/>
	 * TNE rs, rt<br/><br/>
	 * Description:<br/>
	 * The contents of general register rt are compared to general register rs. If<br/>
	 * the contents of general register rs are not equal to the contents of general<br/>
	 * register rt, a trap exception occurs.<br/>
	 * The code field is available for use as software parameters, but is retrieved<br/>
	 * by the exception handler only by loading the contents of the memory word<br/>
	 * containing the instruction.<br/><br/>
	 * Operation:<br/>
	 * T: if GPR[rs] != GPR[rt] then TrapException
	 * @throws mips.exceptions.TrapException
	 */
	@Override	
	public final void execute(final int instruction) throws mips.exceptions.TrapException {
		
		mips.instructions.Instruction.RS = (instruction >> 21) & 0x0000001F;
		mips.instructions.Instruction.RT = (instruction >> 16) & 0x0000001F;

		if(mips.R4300i.GPR[mips.instructions.Instruction.RS] != mips.R4300i.GPR[mips.instructions.Instruction.RT]) {
			throw new mips.exceptions.TrapException(mips.R4300i.PC,instruction);
		}
		
		mips.R4300i.PC = mips.R4300i.nPC;
		mips.R4300i.nPC = mips.R4300i.nPC + 4;		
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String emit(final int instruction) {
		
		mips.instructions.Instruction.RS = (instruction >> 21) & 0x0000001F;
		mips.instructions.Instruction.RT = (instruction >> 16) & 0x0000001F;

		return	"		if(mips.CPU.GPR["+mips.instructions.Instruction.RS+"] != mips.CPU.GPR["+mips.instructions.Instruction.RT+"]) {\n" + 
				"			throw new mips.exceptions.TrapException(mips.CPU.PC,"+String.format("0x%08X",instruction)+");\n" + 
				"		}\n" + 
				"		\n" + 
				"		mips.CPU.PC = mips.CPU.nPC;\n" + 
				"		mips.CPU.nPC = mips.CPU.nPC + 4;\n";
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName(final int instruction) {
		return getName();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName() {
		return INSTRUCTION_NAME;
	}
}